package com.dews.information.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dews.common.constant.HttpStatus;
import com.dews.common.core.domain.model.LoginUser;
import com.dews.common.core.page.TableDataInfo;
import com.dews.common.utils.SecurityUtils;
import com.dews.information.convert.SubjectCourseConvert;
import com.dews.information.domain.dto.SubjectCourseDTO;
import com.dews.information.domain.dto.SubjectCourseQueryDTO;
import com.dews.information.domain.entity.Subject;
import com.dews.information.domain.entity.SubjectCourse;
import com.dews.information.domain.ro.SubjectCourseRo;
import com.dews.information.domain.vo.SubjectCourseVo;
import com.dews.information.mapper.SubjectCourseMapper;
import com.dews.information.service.ISubjectCourseService;
import com.dews.information.service.ISubjectService;
import com.dews.system.domain.SysDept;
import com.dews.system.domain.SysUser;
import com.dews.system.domain.SysUserRole;
import com.dews.system.mapper.SysUserMapper;
import com.dews.system.mapper.SysUserRoleMapper;
import com.dews.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 专业课程管理Service业务层处理
 *
 * @author qingfeng
 * @date 2024-12-08
 */
@Service
public class SubjectCourseServiceImpl extends ServiceImpl<SubjectCourseMapper, SubjectCourse> implements ISubjectCourseService {

    private SubjectCourseMapper subjectCourseMapper;
    private ISysDeptService sysDeptService;
    private ISubjectService subjectService;
    private SysUserRoleMapper sysUserRoleMapper;
    private SysUserMapper sysUserMapper;


    @Autowired
    public SubjectCourseServiceImpl(SubjectCourseMapper subjectCourseMapper,
                                    ISysDeptService sysDeptService,
                                    ISubjectService subjectService,
                                    SysUserRoleMapper sysUserRoleMapper,
                                    SysUserMapper sysUserMapper) {
        this.subjectCourseMapper = subjectCourseMapper;
        this.sysDeptService = sysDeptService;
        this.subjectService = subjectService;
        this.sysUserRoleMapper = sysUserRoleMapper;
        this.sysUserMapper = sysUserMapper;
    }

    /**
     * 查询专业课程管理列表
     *
     * @param subjectCourseQueryDTO 专业课程管理
     * @return 专业课程管理
     */
    @Override
    public TableDataInfo selectSubjectCourseList(SubjectCourseQueryDTO subjectCourseQueryDTO) {
        Page<SubjectCourse> subjectCoursePage = baseMapper.selectPage(
                new Page<SubjectCourse>(subjectCourseQueryDTO.getPageNo(), subjectCourseQueryDTO.getPageLimit()),
                Wrappers.lambdaQuery(SubjectCourse.class)
                        .eq(ObjectUtil.isNotNull(subjectCourseQueryDTO.getDepId()), SubjectCourse::getDepId, subjectCourseQueryDTO.getDepId())
                        .eq(ObjectUtil.isNotNull(subjectCourseQueryDTO.getSubjectId()), SubjectCourse::getSubjectId, subjectCourseQueryDTO.getSubjectId())
                        .like(StrUtil.isNotBlank(subjectCourseQueryDTO.getCourseName()), SubjectCourse::getCourseName, subjectCourseQueryDTO.getCourseName())
                        .like(ObjectUtil.isNotNull(subjectCourseQueryDTO.getCourseTeacherId()), SubjectCourse::getCourseTeacher, subjectCourseQueryDTO.getCourseTeacherId())
                        .eq(ObjectUtil.isNotNull(subjectCourseQueryDTO.getIsEnable()), SubjectCourse::getIsEnable, subjectCourseQueryDTO.getIsEnable())
        );
        if (CollUtil.isEmpty(subjectCoursePage.getRecords())) {
            return TableDataInfo.builder()
                    .code(HttpStatus.SUCCESS)
                    .msg("查询成功")
                    .rows(Collections.emptyList())
                    .total(subjectCoursePage.getTotal())
                    .build();
        }
        // 封装部门名称
        Map<Long, String> depMap = sysDeptService.selectByIds(
                        subjectCoursePage.getRecords()
                                .stream()
                                .map(SubjectCourse::getDepId)
                                .collect(Collectors.toSet())
                ).stream()
                .collect(Collectors.toMap(
                        SysDept::getDeptId,
                        SysDept::getDeptName
                ));
        // 封装专业名称
        Map<Integer, String> subjectMap = subjectService.list(
                        Wrappers.lambdaQuery(Subject.class)
                                .in(Subject::getId, subjectCoursePage.getRecords()
                                        .stream()
                                        .map(SubjectCourse::getSubjectId)
                                        .collect(Collectors.toSet()))
                ).stream()
                .collect(Collectors.toMap(
                        Subject::getId,
                        Subject::getSubjectName
                ));
        return TableDataInfo.builder()
                .code(HttpStatus.SUCCESS)
                .msg("查询成功")
                .rows(SubjectCourseConvert.INSTANCE.convert(subjectCoursePage.getRecords())
                        .stream()
                        .peek(s -> {
                            s.setDepName(depMap.computeIfAbsent(s.getDepId(), k -> ""));
                            s.setSubjectName(subjectMap.computeIfAbsent(s.getSubjectId(), k -> ""));
                        })
                        .collect(Collectors.toList())
                )
                .total(subjectCoursePage.getTotal())
                .build();
    }


    /**
     * 查询专业课程管理
     *
     * @param id 专业课程管理主键
     * @return 专业课程管理
     */
    @Override
    public SubjectCourse selectSubjectCourseById(Integer id) {
        return baseMapper.selectById(id);
    }

    /**
     * 新增专业课程管理
     *
     * @param subjectCourseDTO 专业课程管理
     * @return 结果
     */
    @Override
    public int insertSubjectCourse(SubjectCourseDTO subjectCourseDTO) {
        SubjectCourse subjectCourse = SubjectCourseConvert.INSTANCE.convert(subjectCourseDTO);
        Subject subject = subjectService.getById(subjectCourseDTO.getSubjectId());
        subjectCourse.setDepId(subject.getDepId());
        return subjectCourseMapper.insert(subjectCourse);

    }

    /**
     * 修改专业课程管理
     *
     * @param subjectCourseDTO 专业课程管理
     * @return 结果
     */
    @Override
    public int updateSubjectCourse(SubjectCourseDTO subjectCourseDTO) {
        SubjectCourse subjectCourse = SubjectCourseConvert.INSTANCE.convert(subjectCourseDTO);
        return subjectCourseMapper.updateById(subjectCourse);
    }

    /**
     * 批量删除专业课程管理
     *
     * @param ids 需要删除的专业课程管理主键
     * @return 结果
     */
    @Override
    public int deleteSubjectCourseByIds(List<Integer> ids) {
        return subjectCourseMapper.deleteBatchIds(ids);
    }

    /**
     * 删除专业课程管理信息
     *
     * @param id 专业课程管理主键
     * @return 结果
     */
    @Override
    public int deleteSubjectCourseById(Integer id) {
        return subjectCourseMapper.deleteById(id);
    }

    @Override
    public List<SysUser> getTeacherList() {
        Set<Long> userIdSet = sysUserRoleMapper.selectList(
                        Wrappers.lambdaQuery(SysUserRole.class)
                                .eq(SysUserRole::getRoleId, 100)
                ).stream()
                .map(SysUserRole::getUserId)
                .collect(Collectors.toSet());
        if (CollUtil.isEmpty(userIdSet)) {
            return Collections.emptyList();
        }
        return sysUserMapper.selectList(
                Wrappers.lambdaQuery(SysUser.class)
                .in(SysUser::getUserId, userIdSet)
        );
    }

    @Override
    public List<SubjectCourseRo> getTeacherCourseList() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<SubjectCourse> list = this.list(
                new LambdaQueryWrapper<SubjectCourse>()
                        .like(SubjectCourse::getCourseTeacher, loginUser.getUserId())
        );
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 封装部门名称
        Map<Long, String> depMap = sysDeptService.selectByIds(
                        list.stream()
                                .map(SubjectCourse::getDepId)
                                .collect(Collectors.toSet())
                ).stream()
                .collect(Collectors.toMap(
                        SysDept::getDeptId,
                        SysDept::getDeptName
                ));
        // 封装专业名称
        Map<Integer, String> subjectMap = subjectService.list(
                        Wrappers.lambdaQuery(Subject.class)
                                .in(Subject::getId, list.stream()
                                        .map(SubjectCourse::getSubjectId)
                                        .collect(Collectors.toSet()))
                ).stream()
                .collect(Collectors.toMap(
                        Subject::getId,
                        Subject::getSubjectName
                ));

        List<SubjectCourseVo> collect = SubjectCourseConvert.INSTANCE.convert(list)
                .stream()
                .peek(s -> {
                    s.setDepName(depMap.computeIfAbsent(s.getDepId(), k -> ""));
                    s.setSubjectName(subjectMap.computeIfAbsent(s.getSubjectId(), k -> ""));
                })
                .collect(Collectors.toList());

        // 分组按标签封装数据
        ArrayList<SubjectCourseRo> subjectCourseRos = new ArrayList<>();
        subjectCourseRos.add(
                SubjectCourseRo.builder()
                        .activeName(-1)
                        .label("全部")
                        .subjectCourseList(collect)
                        .build()
        );

        collect.stream()
                .collect(Collectors.groupingBy(SubjectCourseVo::getSubjectName))
                .entrySet()
                .stream()
                .forEach(e -> {
                    subjectCourseRos.add(
                            SubjectCourseRo.builder()
                                    .activeName(e.getValue().get(0).getSubjectId())
                                    .label(e.getKey())
                                    .subjectCourseList(e.getValue())
                                    .build()
                    );
                });
        return subjectCourseRos;
    }

}
